/*
 * Copyright (c) 2020 Carnegie Lee
 * All rights reserved
 */
package com.geekc.threadpool.pool.impl;

import com.geekc.threadpool.constant.ThreadPoolConst;
import com.geekc.threadpool.pool.ThreadPool;
import com.geekc.threadpool.thread.DefaultThreadFactory;

import java.util.concurrent.*;

/**
 * Thead Pool默认实现类
 * @author Carnegie Lee
 */
public class DefaultThreadPool implements ThreadPool {

    /** JDK线程池 */
    private ThreadPoolExecutor threadPoolExecutor;
    /** 线程池构建器 */
    private ThreadPoolBuilder threadPoolBuilder = new ThreadPoolBuilder();

    public DefaultThreadPool() {}

    /**
     * 构建ThreadPoolExecutor
     * @return DefaultThreadPool
     */
    public DefaultThreadPool build() {
        this.threadPoolExecutor = new ThreadPoolExecutor(threadPoolBuilder.getCorePoolSize(),
                threadPoolBuilder.getMaximumPoolSize(),
                threadPoolBuilder.getKeepAliveTime(),
                threadPoolBuilder.getTimeUnit(),
                threadPoolBuilder.getBlockingQueue(),
                threadPoolBuilder.getThreadFactory(),
                threadPoolBuilder.getRejectedExecutionHandler());
        return this;
    }

    @Override
    public void execute(Runnable runnable) {
        this.threadPoolExecutor.execute(runnable);
    }

    @Override
    public <T> Future<T> submit(Callable<T> callable) {
        return this.threadPoolExecutor.submit(callable);
    }

    @Override
    public void shutdown() {
        this.threadPoolExecutor.shutdown();
    }

    /**
     * 设置核心线程数
     * @param corePoolSize 核心线程数
     * @return ThreadPoolBuilder
     */
    public ThreadPoolBuilder corePoolSize(int corePoolSize) {
        threadPoolBuilder.setCorePoolSize(corePoolSize);
        return threadPoolBuilder;
    }

    /**
     * 设置最大线程数
     * @param maximumPoolSize 最大线程数
     * @return ThreadPoolBuilder
     */
    public ThreadPoolBuilder maximumPoolSize(int maximumPoolSize) {
        threadPoolBuilder.setMaximumPoolSize(maximumPoolSize);
        return threadPoolBuilder;
    }

    /**
     * 设置空闲线程存活时间
     * @param keepAliveTime 空闲线程存活时间
     * @return ThreadPoolBuilder
     */
    public ThreadPoolBuilder keepAliveTime(long keepAliveTime) {
        threadPoolBuilder.setKeepAliveTime(keepAliveTime);
        return threadPoolBuilder;
    }

    /**
     * 设置空闲线程存活单位
     * @param timeUnit 空闲线程存活单位
     * @return ThreadPoolBuilder
     */
    public ThreadPoolBuilder timeUnit(TimeUnit timeUnit) {
        threadPoolBuilder.setTimeUnit(timeUnit);
        return threadPoolBuilder;
    }

    /**
     * 设置存放任务的线程阻塞队列
     * @param blockingQueue 存放任务的线程阻塞队列
     * @return ThreadPoolBuilder
     */
    public ThreadPoolBuilder blockingDeque(BlockingQueue blockingQueue) {
        threadPoolBuilder.setBlockingQueue(blockingQueue);
        return threadPoolBuilder;
    }

    /**
     * 设置工作线程名称前缀
     * @param prefixName 工作线程名称前缀
     * @return ThreadPoolBuilder
     */
    public ThreadPoolBuilder prefixThreadName(String prefixName) {
        ThreadFactory threadFactory = new DefaultThreadFactory(prefixName);
        threadPoolBuilder.setThreadFactory(threadFactory);
        return threadPoolBuilder;
    }

    /**
     * 设置线程饱和策略
     * @param rejectedExecutionHandler 线程饱和策略
     * @return ThreadPoolBuilder
     */
    public ThreadPoolBuilder rejectPolicy(RejectedExecutionHandler rejectedExecutionHandler) {
        threadPoolBuilder.setRejectedExecutionHandler(rejectedExecutionHandler);
        return threadPoolBuilder;
    }

    private class ThreadPoolBuilder {
        /** 核心线程数 */
        private int corePoolSize = ThreadPoolConst.DEFAULT_CORE_POOL_SIZE_COMPUTE;
        /** 最大线程数 */
        private int maximumPoolSize = ThreadPoolConst.DEFAULT_MAXIMUM_POOL_SIZE;
        /** 空闲线程存活时间 */
        private long keepAliveTime = ThreadPoolConst.DEFAULT_KEEPALIVE_TIME;
        /** 空闲线程存活单位 */
        private TimeUnit timeUnit = ThreadPoolConst.DEFAULT_TIME_UNIT;
        /** 存放任务的线程阻塞队列 */
        private BlockingQueue blockingQueue = new ArrayBlockingQueue<Runnable>(ThreadPoolConst.DEFAULT_BLOCKING_QUEUE_SIZE);
        /** 线程工厂 */
        private ThreadFactory threadFactory = new DefaultThreadFactory(ThreadPoolConst.DEFAULT_PREFIX_THREAD_NAME);
        /** 线程饱和策略 */
        private RejectedExecutionHandler rejectedExecutionHandler = new ThreadPoolExecutor.DiscardOldestPolicy();

        public void setCorePoolSize(int corePoolSize) {
            this.corePoolSize = corePoolSize;
        }

        public void setMaximumPoolSize(int maximumPoolSize) {
            this.maximumPoolSize = maximumPoolSize;
        }

        public void setKeepAliveTime(long keepAliveTime) {
            this.keepAliveTime = keepAliveTime;
        }

        public void setTimeUnit(TimeUnit timeUnit) {
            this.timeUnit = timeUnit;
        }

        public void setBlockingQueue(BlockingQueue blockingQueue) {
            this.blockingQueue = blockingQueue;
        }

        public void setThreadFactory(ThreadFactory threadFactory) {
            this.threadFactory = threadFactory;
        }

        public void setRejectedExecutionHandler(RejectedExecutionHandler rejectedExecutionHandler) {
            this.rejectedExecutionHandler = rejectedExecutionHandler;
        }

        public int getCorePoolSize() {
            return corePoolSize;
        }

        public int getMaximumPoolSize() {
            return maximumPoolSize;
        }

        public long getKeepAliveTime() {
            return keepAliveTime;
        }

        public TimeUnit getTimeUnit() {
            return timeUnit;
        }

        public BlockingQueue getBlockingQueue() {
            return blockingQueue;
        }

        public ThreadFactory getThreadFactory() {
            return threadFactory;
        }

        public RejectedExecutionHandler getRejectedExecutionHandler() {
            return rejectedExecutionHandler;
        }
    }
}
